package com.ztgf.message.api.handler;

import com.alibaba.fastjson.JSON;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.message.model.dto.ResponseDTO;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @Description ：
 * @Author ： mx.li
 * @Date ： 2018/10/09 15:50
 */

@Slf4j
public class ChannelRepository {

    private ChannelRepository(){

    }

    private static ChannelRepository instance = new ChannelRepository();

    public static ChannelRepository getInstance(){
        return instance;
    }

    //clientId 绑定通道ID chennelId， clientId
    private ConcurrentMap<String, String> clientMap = new ConcurrentHashMap<>();

    //clientId 绑定通道
    private ConcurrentMap<String, Channel> channelCache = new ConcurrentHashMap<String, Channel>();

    public int size() {
        return this.channelCache.size();
    }


    /**
     * 获取所有通道
     * @return
     */
    public Set<Channel> getAll(){
        Set<Channel> result = new HashSet<>();
        if(channelCache != null && channelCache.size() > 0){
            for (String key : channelCache.keySet()){
                result.add(channelCache.get(key));
            }
        }
        return result;
    }

    /**
     * 获取根据clientId通道
     * @return
     */
    public Channel getChannelByClientId(String clientId){
        Channel channel = channelCache.get(clientId);
        return channel;
    }
    /**
     * 获取根据clientId通道
     * @return
     */
    public String getChannelIdByClientId(String clientId){
        Channel channel = channelCache.get(clientId);
        String result = null;
        if(channel != null){
            result = channel.id().toString();
        }
        return result;
    }
    /**
     * 获取根据clientId通道
     * @return
     */
    public Channel getChannelById(String channelId){
        String clientId = clientMap.get(channelId);
        return getChannelByClientId(clientId);
    }

    /**
     * 根据渠道ID 获取clientId
     * @param channelId
     * @return
     */
    public String getClientIdByChanneId(String channelId){
        return clientMap.get(channelId);
    }

    public void put(String clientId, Channel channel){
        String channelId = channel.id().toString();
        clientMap.put(channelId, clientId);
        channelCache.put(clientId, channel);
    }

    public void remove(Channel channel){
        String channelId = channel.id().toString();
        String clientId = clientMap.get(channelId);
        if(StrUtils.isNotEmpty(clientId)){
            try {
                clientMap.remove(channelId);
                channelCache.remove(clientId);
            } catch (Exception e){
                log.error("removeAll is error", e);
            }
        }
    }

    public void sendMessage(String clientId, Object msg){
        try {
            String msgStr = JSON.toJSONString(msg);
            //String encodeStr = AESUtil.encrypt(msgStr);
            if (channelCache.get(clientId) != null) {
                channelCache.get(clientId).writeAndFlush(new TextWebSocketFrame(msgStr));
            }
        } catch (Exception e){
            log.error("sendMessage is error", e);
        }
    }

    public void sendMessage(String clientId, String method, String messageId, Object msg){
        try {
            ResponseDTO responseDTO = new ResponseDTO();
            responseDTO.setCode(0);
            responseDTO.setMsg("成功");
            responseDTO.setMethod(method);
            responseDTO.setMessageId(messageId);
            responseDTO.setData(msg);
            String msgStr = JSON.toJSONString(responseDTO);
            //String encodeStr = AESUtil.encrypt(msgStr);
            if (channelCache.get(clientId) != null) {
                channelCache.get(clientId).writeAndFlush(new TextWebSocketFrame(msgStr));
            }
        } catch (Exception e){
            log.error("sendMessage is error", e);
        }
    }

    public void sendMessage(Channel channel, Object msg){
        try {
            String msgStr = JSON.toJSONString(msg);
            //String encodeStr = AESUtil.encrypt(msgStr);
            channel.writeAndFlush(new TextWebSocketFrame(msgStr));
        } catch (Exception e){
            log.error("sendMessage is error", e);
        }
    }

    public void sendMessage(Set<Channel> list, Object msg){
        for (Channel channel: list) {
            sendMessage(channel, msg);
        }
    }


}
